<?php

require_once(dirname(__FILE__).'/Bootstrap/Interface.php');
require_once(dirname(__FILE__).'/Mvc/Interface.php');

class Quad_Bootstrap /*extends Quad_Observable*/ implements Quad_Bootstrap_Interface, Quad_MVC_Interface {

	public $rewriteCallbacks = array();
	public $includeDirs;
	public $routerClass;
	public $frontControllerClass;
	public $viewClass;
	public $runType;
	protected $_url;
	protected $_router;
	protected $_frontController;
	
	public function __construct($type = 'rewrite') {
    $this->includeDirs = array(
      '',
      dirname(__FILE__) . '/../',
    );
		spl_autoload_register(array($this, 'loadClasses'));
		error_reporting(E_ALL | ~E_STRICT | ~E_NOTICE);
		//set_error_handler(array('Quad_Error', 'handler'));
		$this->setRunType($type);
	}
	
	public function setRunType($type) {
		$this->runType = $type;
		switch ($type) {
			case 'rewrite':
				$this->routerClass = 'Quad_Router_HttpPretty';
        $this->frontControllerClass = 'Quad_FrontController';
        $this->viewClass = 'Quad_View_Html';
				break;
				
      case 'plain':
        $this->routerClass = 'Quad_Router_HttpPlain';
        $this->frontControllerClass = 'Quad_FrontController';
        $this->viewClass = 'Quad_View_Html';
        break;				
				
      case 'shell':
        $this->routerClass = 'Quad_Router_Shell';
        $this->frontControllerClass = 'Quad_FrontController';
        //$this->viewClass = 'Quad_View_Shell';
        $this->viewClass = 'Quad_View_Html';
        break;				
				
			case 'unit':
        $this->routerClass = 'Quad_Router_Unit';
        $this->frontControllerClass = 'Quad_FrontController';
        $this->viewClass = 'Quad_View_Unit';				
				break;
				
			case 'soap':
        $this->routerClass = 'Quad_Router_Soap';
        $this->frontControllerClass = 'Quad_FrontController'; 				
        $this->viewClass = 'Quad_View_Soap';				
				break;
		}
	}
	
  public function run() {
  	try {
	    $this->getFrontController()->dispatch();
  	}
  	catch (Exception $e) {
  		Quad_Error::trigger($e);
  	}
  }
	
	public function getRouter() {
		if ($this->_router === null) {
			$this->_router = new $this->routerClass($this);
		}
		return $this->_router;
	}
	
	public function getFrontController() {
		if ($this->_frontController === null) {
			$cls = $this->frontControllerClass;
			$this->_frontController = new $cls($this);
		}
		return $this->_frontController;		
	}
	
	public function getController() {
		return $this->getFrontController()->getController();
	}
	
	public function getView() {
		return $this->getFrontController()->getController()->getView();
	}
  
  public function restart() {
  	unset($this->_url);
  	unset($this->_router);
  	unset($this->_frontController);
  }
	
	public function addRewrite($callback) {
		$this->rewriteCallbacks[] = $callback;
	}
	
	public function addIncludeDir($path) {
		$this->includeDirs[] = $path;
	}
	
	public function loadClasses($class) {		
		$file = '/' . str_replace('_', '/', $class) . '.php';
		foreach ($this->includeDirs as $path) {
			if (is_file($path . $file)) {
				require_once($path . $file);
				return;
			}
		}
	}
	
	public function getUrl() {
		if ($this->_url === null) {
			// http://dev.textcube.org/changeset/7064/trunk/rewrite.php
			// IIS 7.0 and URL Rewrite Module CTP, but non-ASCII URLs are NOT supported. 
	    if (isset($_SERVER['HTTP_X_ORIGINAL_URL'])) { 
	      $url = $_SERVER['HTTP_X_ORIGINAL_URL']; 
	      
	    } // IIS 5.x/6.0/7.0 and Ionics ISAPI Rewrite Filter 
	    else if (isset($_SERVER['HTTP_X_REWRITE_URL'])/* && strpos($_SERVER['REQUEST_URI'], 'rewrite.php') !== FALSE*/) { 
	      $url = urldecode($_SERVER['HTTP_X_REWRITE_URL']); 
	    }
	    else {
	    	$url = $_SERVER['REQUEST_URI'];
	    }			
			$this->_url = $this->_applyRewrites($url);
		}
		return $this->_url;
	}
	
	protected function _applyRewrites($url) {
		foreach ($this->rewriteCallbacks as $fn) {
			$fn($url); // function must modify by reference
		}
		return $url;
	}
	
}